package net.cassite.daf4j.jpa;

import net.cassite.daf4j.Parameter;
import net.cassite.daf4j.ParameterAggregate;
import net.cassite.daf4j.ParameterComparable;
import net.cassite.daf4j.PreResult;
import net.cassite.daf4j.ds.*;

/**
 * 将所有条件解释为JPQL语句
 */
public class JPQLConditionParser implements ConditionParser<JPQLContext, String> {
        private ObjectResolver<JPQLContext, String> objectResolver;

        @Override
        public String gt(JPQLContext jpqlContext, ParameterComparable<?> parameterComparable, Object o) throws Exception {
                return objectResolver.resolve(jpqlContext, parameterComparable) + " > " + objectResolver.resolve(jpqlContext, o);
        }

        @Override
        public String lt(JPQLContext jpqlContext, ParameterComparable<?> parameterComparable, Object o) throws Exception {
                return objectResolver.resolve(jpqlContext, parameterComparable) + " < " + objectResolver.resolve(jpqlContext, o);
        }

        @Override
        public String eq(JPQLContext jpqlContext, Parameter parameter, Object o) throws Exception {
                return objectResolver.resolve(jpqlContext, parameter) + " = " + objectResolver.resolve(jpqlContext, o);
        }

        @Override
        public String ge(JPQLContext jpqlContext, ParameterComparable<?> parameterComparable, Object o) throws Exception {
                return objectResolver.resolve(jpqlContext, parameterComparable) + " >= " + objectResolver.resolve(jpqlContext, o);
        }

        @Override
        public String le(JPQLContext jpqlContext, ParameterComparable<?> parameterComparable, Object o) throws Exception {
                return objectResolver.resolve(jpqlContext, parameterComparable) + " <= " + objectResolver.resolve(jpqlContext, o);
        }

        @Override
        public String ne(JPQLContext jpqlContext, Parameter parameter, Object o) throws Exception {
                return objectResolver.resolve(jpqlContext, parameter) + " <> " + objectResolver.resolve(jpqlContext, o);
        }

        @Override
        public String between(JPQLContext jpqlContext, ParameterComparable<?> parameterComparable, Object o, Object o1) throws Exception {
                return objectResolver.resolve(jpqlContext, parameterComparable) + " BETWEEN " + objectResolver.resolve(jpqlContext, o) + " AND " + objectResolver.resolve(jpqlContext, o1);
        }

        @Override
        public String in(JPQLContext jpqlContext, Parameter parameter, PreResult<?> preResult) throws Exception {
                return objectResolver.resolve(jpqlContext, parameter) + " IN(" + objectResolver.resolve(jpqlContext, preResult) + ")";
        }

        @Override
        public String notIn(JPQLContext jpqlContext, Parameter parameter, PreResult<?> preResult) throws Exception {
                return objectResolver.resolve(jpqlContext, parameter) + " NOT IN(" + objectResolver.resolve(jpqlContext, preResult) + ")";
        }

        @Override
        public String like(JPQLContext jpqlContext, Parameter parameter, Object[] objects) throws Exception {
                String str = objectResolver.resolve(jpqlContext, parameter) + " LIKE ";
                boolean isFirst = true;
                for (Object o : objects) {
                        if (isFirst) {
                                isFirst = false;
                        } else {
                                str += ", ";
                        }
                        str += objectResolver.resolve(jpqlContext, o);
                }
                return str;
        }

        @Override
        public String isNull(JPQLContext jpqlContext, Parameter parameter) throws Exception {
                return objectResolver.resolve(jpqlContext, parameter) + " IS NULL";
        }

        @Override
        public String isNotNull(JPQLContext jpqlContext, Parameter parameter) throws Exception {
                return objectResolver.resolve(jpqlContext, parameter) + " IS NOT NULL";
        }

        @Override
        public String member(JPQLContext jpqlContext, Parameter parameter, ParameterAggregate parameterAggregate) throws Exception {
                return objectResolver.resolve(jpqlContext, parameter) + " MEMBER " + objectResolver.resolve(jpqlContext, parameterAggregate);
        }

        @Override
        public String reverseMember(JPQLContext jpqlContext, ParameterAggregate parameterAggregate, Object o) throws Exception {
                return objectResolver.resolve(jpqlContext, o) + " MEMBER " + objectResolver.resolve(jpqlContext, parameterAggregate);
        }

        @Override
        public String notMember(JPQLContext jpqlContext, Parameter parameter, ParameterAggregate parameterAggregate) throws Exception {
                return objectResolver.resolve(jpqlContext, parameter) + " NOT MEMBER " + objectResolver.resolve(jpqlContext, parameterAggregate);
        }

        @Override
        public String reverseNotMember(JPQLContext jpqlContext, ParameterAggregate parameterAggregate, Object o) throws Exception {
                return objectResolver.resolve(jpqlContext, o) + " NOT MEMBER " + objectResolver.resolve(jpqlContext, parameterAggregate);
        }

        @Override
        public void setObjectResolver(ObjectResolver<JPQLContext, String> objectResolver) {
                this.objectResolver = objectResolver;
        }
}
